/**
 * 文件加密&解密2 https://www.bilibili.com/video/BV1vs411n7TH?p=122
 */
#include <string.h>
#include "../Utils/Random.h"
#include "../Utils/FileIOUtils.h"

static char *FILE_READ_PATH = "../Read_Write_Test/test.txt";
static char *FILE_ENCODE_PATH = "../Read_Write_Test/7.文件加密2.txt";
static char *FILE_DECODE_PATH = "../Read_Write_Test/7.文件解密2.txt";

static void encode();
static void decode();

int main() {
    //1.加密
    encode();
    //2.解密
    decode();

    return EXIT_SUCCESS;
}

//1.加密
static void encode() {
    FILE *read = file_open_r(FILE_READ_PATH);
    FILE *write = file_open_w(FILE_ENCODE_PATH);
    if (!read || !write) return;
    int SIZE = 1024;
    char *str = malloc(sizeof(char) * SIZE);
    while (!file_eof(read)) {
        memset(str, 0, sizeof(char) * SIZE);    //清空
        char *v0 = file_gets(str, (int) sizeof(char) * SIZE, read);
        for (int i = 0; i < strlen(str); ++i) {
            /**
             * char转short:
             * h, ASCII值: 104
             *           0110 1000  //104 对应的2进制
             *           0111 1111  //char 最大值: 127
             * 0100 1011 0110 1000  //低位104 + 高位随机数
             * 0000 0001 0000 0000  //高位最小值: 256
             * 0111 1111 0000 0000  //高位最大值: 32512
             *
             * ∵只修改高位, 不修改低位. ∴增加的值都是高位最小值256的倍数!
             * 高位最大值 ÷ 高位最小值 = 32512/256=127
             * 将char转成short,  1个字节-->2个字节(8位-->16位),  将高位加上随机数
             */
            short value = (short) str[i];
            value += (getRandom() % 127 + 1) * 256; //value + 256~32512
            value *= -1;                            //用负号分隔开, 否则读不出来(也可以用其它符号)
            file_printf(write, "%hd", value);
        }
    }
    printf("加密完成: %s\n", FILE_ENCODE_PATH);

    free(str);
    file_close(read);
    file_close(write);
}

//2.解密
static void decode() {
    FILE *read = file_open_r(FILE_ENCODE_PATH);
    FILE *write = file_open_w(FILE_DECODE_PATH);
    if (!read || !write) return;
    short hd;
    char c;
    while (!file_eof(read)) {
        int count = file_scanf(read, "%hd", &hd);   //注意: 要写成 %hd
        hd *= -1;                           //转换成正数
        c = (char) hd;                      //short-->char, 高位溢出
        file_putc(c, write);
    }
    printf("加密完成: %s\n", FILE_DECODE_PATH);

    file_close(read);
    file_close(write);
}
